#ifndef _MASKVOLUME_H_
#define _MASKVOLUME_H_

#include <string.h>

//#ifndef _WIN32
//typedef bool            BOOL;
//#endif
typedef unsigned char * LPBYTE;
typedef unsigned char   BYTE;

class RxMaskVolume  
{
public:
	LPBYTE m_pbyMask;
	int m_iMaskSize;
	int m_iVolX, m_iVolY, m_iVolZ;

public:
	RxMaskVolume();
	virtual ~RxMaskVolume();

public:
	inline void SetMask(const int& iOffset);
	inline void SetMask(const int& iVolX, const int& iVolY, const int& iVolZ);
	inline void ClearMask(const int& iOffset);
	inline void ClearMask(const int& iVolX, const int& iVolY, const int& iVolZ);
	inline unsigned char GetMask(const int& iOffset);
	inline unsigned char GetMask(const int& iVolX, const int& iVolY, const int& iVolZ);
	inline unsigned char GetMinMaxMask2x2(const int& iVolX, const int& iVolY, const int& iVolZ);
	inline unsigned char GetMinMaxMask8x8(const int& iVolX, const int& iVolY, const int& iVolZ);

	inline unsigned char * GetMaskPtr(const int & iVolZ);
	inline unsigned char * GetMaskPtr(const int & iVolZ, const int & iVolY);

	inline unsigned char * GetMaskPtr()	{return m_pbyMask;}

	inline int GetMaskSizeInByte() {return m_iMaskSize;}

	inline void ResetMask(BYTE byFill = 0xFF);

	bool CreateMaskVolume(int iVolX, int iVolY, int iVolZ, char chFill = 0);
	bool CreateNULLMask(int iVolX, int iVolY, int iVolZ);
	void DestroyMaskVolume();

	RxMaskVolume operator = (const RxMaskVolume &maskSrc);
	void operator |= (const RxMaskVolume &maskSrc);
	void AssignMaskVolume(unsigned char* pbyNewMaskVol);
	bool CopyMaskVolume(const RxMaskVolume* pmvSrc);

protected:
};


void RxMaskVolume::ResetMask(BYTE byFill /* = 0xff */)
{
	memset(m_pbyMask, byFill, m_iMaskSize);
}

inline void RxMaskVolume::SetMask(const int& iOffset)
{
	int iQuotient, iRemainder;
	iQuotient = iOffset >> 3;
	iRemainder = iOffset & 0x07;
	m_pbyMask[iQuotient] = m_pbyMask[iQuotient] | (0x01 << (7 - iRemainder));
}

inline void RxMaskVolume::SetMask(const int& iVolX, const int& iVolY, const int& iVolZ)
{
	int iQuotient, iRemainder, iOffset;
	iOffset = m_iVolX * m_iVolY * iVolZ + m_iVolX * iVolY + iVolX;

	iQuotient = iOffset >> 3;
	iRemainder = iOffset & 0x07;
	m_pbyMask[iQuotient] = m_pbyMask[iQuotient] | (0x01 << (7 - iRemainder));
}

inline void RxMaskVolume::ClearMask(const int& iOffset)
{
	int iQuotient, iRemainder;
	iQuotient = iOffset >> 3;
	iRemainder = iOffset & 0x07;
	m_pbyMask[iQuotient] = m_pbyMask[iQuotient] & (~(0x01 << (7 - iRemainder)));
}

inline void RxMaskVolume::ClearMask(const int& iVolX, const int& iVolY, const int& iVolZ)
{
	int iQuotient, iRemainder, iOffset;
	iOffset = m_iVolX * m_iVolY * iVolZ + m_iVolX * iVolY + iVolX;

	iQuotient = iOffset >> 3;
	iRemainder = iOffset & 0x07;
	m_pbyMask[iQuotient] = m_pbyMask[iQuotient] & (~(0x01 << (7 - iRemainder)));
}

inline unsigned char RxMaskVolume::GetMask(const int& iOffset)
{
	int iQuotient, iRemainder;
	iQuotient = iOffset >> 3;
	iRemainder = iOffset & 0x07;
	return (m_pbyMask[iQuotient] >> (7 - iRemainder)) & 0x01;
}

inline unsigned char RxMaskVolume::GetMask(const int& iVolX, const int& iVolY, const int& iVolZ)
{
	int iQuotient, iRemainder, iOffset;
	iOffset = m_iVolX * m_iVolY * iVolZ + m_iVolX * iVolY + iVolX;

	iQuotient = iOffset >> 3;
	iRemainder = iOffset & 0x07;
	return (m_pbyMask[iQuotient] >> (7 - iRemainder)) & 0x01;
}

inline unsigned char * RxMaskVolume::GetMaskPtr(const int & iVolZ)
{
	int iQuotient, iOffset;
	iOffset = m_iVolX * m_iVolY * iVolZ;

	iQuotient = iOffset >> 3;
	return &(m_pbyMask[iQuotient]);
}

inline unsigned char * RxMaskVolume::GetMaskPtr(const int & iVolZ, const int & iVolY)
{
	int iQuotient, iOffset;
	iOffset = m_iVolX * m_iVolY * iVolZ + m_iVolX * iVolY;

	iQuotient = iOffset >> 3;
	return &(m_pbyMask[iQuotient]);
}

#endif 

